#ifndef __FACE_OTA_H__
#define __FACE_OTA_H__

#include "component.h"
#include "device.h"

#define FACEOTA_SWAP16(n) ((((uint16_t)(n) >> 8) & 0x00FF) | (((uint16_t)(n) << 8) & 0xFF00))
#define FACEOTA_SWAP32(n) (((((uint32_t)n) >> 24) & 0xFF) | (((uint32_t)(n) >> 8) & 0xFF00) | (((uint32_t)(n) << 8) & 0xFF0000) | (((uint32_t)(n) << 24) & 0xFF000000))


#define FACE_MID_REPLY 0x00 		//模块对主控发送出的命令的应答
#define FACE_MID_NOTE 0x01  		//模块主动发给主控的信息
#define FACE_MID_RESET 0x10				 // stop and clear all in-processing messages. enter standby mode
#define FACE_MID_GETSTATUS 0x11			 // to ping the module and get the status
#define FACE_MID_GET_VERSION 0x30		 // get version information
#define FACE_MID_START_OTA 0x40			 // ask the module to enter OTA mode
#define FACE_MID_STOP_OTA 0x41			 // ask the module to exit OTA mode
#define FACE_MID_GET_OTA_STATUS 0x42		 // query the current ota status
#define FACE_MID_OTA_HEADER 0x43			 // the ota header data
#define FACE_MID_OTA_PACKET 0x44			 // the data packet, carries real firmware data
#define FACE_MID_INIT_ENCRYPTION 0x50	 // initialize encrypted communication
#define FACE_MID_CONFIG_BAUDRATE 0x51	 // config uart baudrate
#define FACE_MID_SET_RELEASE_ENC_KEY 0x52 // set release encrypted key(Warning!!!:Once set, the KEY will not be able to modify)
#define FACE_MID_SET_DEBUG_ENC_KEY 0x53	 // set debug encrypted key


/* 锁命令发出后，模组应答的结果 */
#define FACE_MR_SUCCESS 0x00				  //成功
#define FACE_MR_REJECTED 0X01			  //模块拒接该命令
#define FACE_MR_ABORTED 0x02				  //录入/解锁算法已终止
#define FACE_MR_FAILED4_CAMERA 0X04		  //相机打开失败
#define FACE_MR_FAILED4_UNKNOWNREASON 0x05 //未知错误
#define FACE_MR_FAILED4_INVALIDPARAM 0x06  //无效的参数
#define FACE_MR_FAILED4_NOMEMORY 0x07	  //内存不足
#define FACE_MR_FAILED4_UNKNOWNUSER 0x08	  //没有已录入的用户
#define FACE_MR_FAILED4_MAXUSER 0x09		  //录入超过最大用户数量
#define FACE_MR_FAILED4_FACEENROLLED 0x10  //人脸已录入
#define FACE_MR_FAILED4_LIVENESSCHECK 0x12 //活体检测失败
#define FACE_MR_FAILED4_TIMEOUT 0x13		  //录入或解锁超时
#define FACE_MR_FAILED4_AUTHORIZATION 0x14 //加密芯片授权失败
#define FACE_MR_FAILED4_WITHOUTSMILE 0x16  //验证未微笑
#define FACE_MR_FAILED4_READ_FILE 0x19	  //读文件失败
#define FACE_MR_FAILED4_WRITE_FILE 0x20	  //写文件失败
#define FACE_MR_FAILED4_NO_ENCRYPT 0x21	  //通信协议未加密

/*加密模式*/
#define FACE_ENCMODE_DEFAULT 0x00 //默认模式
#define FACE_ENCMODE_AES 0x01		//AES加密
#define FACE_ENCMODE_SMPL 0x02	//取反异或加密


typedef struct
{
    uint16_t stx;  //帧头同步字
    uint8_t msgID; //消息ID
    uint16_t len;  //data数据长度
    uint8_t data[]; //命令
}s_protocol_data_t;

/*启动OTA升级*/
typedef struct
{
	uint8_t v_primary;	 // primary version number
	uint8_t v_secondary; //secondary version number
	uint8_t v_revision;	 //revision number
						 //uint8_t ota_type;     //ota partition: 0:OS, 1:facelib
} face_msg_startota_data;

/* 锁发送设置波特率消息结构 */
typedef struct
{
	uint8_t baudrate_index; //1: is 115200 (115200*1); 2 is 230400 (115200*2); 3 is 460800 (115200*4); 4 is 1500000
} face_msg_config_baudrate;

/*锁发送固件包头信息*/
typedef struct
{
	uint8_t fsize_b[4];	 // OTA FW file size int -> [b1, b2, b3, b4] OTA升级包的大小
	uint8_t num_pkt[4];	 // number packet to be divided for trans ferring, int -> [b1, b2, b3, b4] 分包的个数
	uint8_t pkt_size[2]; // raw data size of single packet分包的大小，最大不超过4KBytes
	uint8_t md5_sum[32]; // md5 check sum 升级包的md5
} face_msg_otaheader_data;

/*锁发送固件包给人脸模组*/
typedef struct
{
	uint16_t pid;	// the packet id
	uint16_t psize; // the size of this package
	uint8_t data[]; // data 0 start
} face_msg_otapacket_data;

/*人脸查询OTA状态应答*/
typedef struct
{
	uint8_t ota_status;	 //4：表示处于 OTA状态
	uint16_t next_pid_e; //传输固件包的起始序号
} face_msg_reply_getOtaStatus_data;

/*发送密钥设置*/
typedef struct
{
	uint8_t seed[4];	// 随机序列
	uint8_t mode;		// 指定 mode 0
	uint8_t crttime[4]; // 同步主控时间给模组 (时间戳)
} face_msg_init_encryption_data;

/* 锁发送加密key的逻辑*/
typedef struct
{
	uint8_t enc_key_number[16]; //
} face_msg_enc_key_number_data;

typedef enum
{
	FACE_OTA_READY,			//ota准备就绪
	FACE_OTA_PROCESS,		//ota处理中
	FACE_OTA_SUCCESS,		//ota成功
	FACE_OTA_ERROR,			//ota失败		
	FACE_OTA_ERROR_TIMEOUT,			//ota超时		
}FaceOTAResult_enum_t;


typedef struct
{
	FaceOTAResult_enum_t ota_result;		//ota结果		
}FaceOTAMsg_t;

static ErrorStatus FaceOTA_PowerOn(void);
static ErrorStatus FaceOTA_Start(uint32_t file_len, char *md5, uint32_t mtu);
static ErrorStatus FaceOTA_Wifi_Module_Start(uint32_t file_len, uint32_t mtu);
static ErrorStatus FaceOTA_StartTest(void);
// static ErrorStatus FaceOTA_SendUpgradePack(face_msg_otapacket_data *data);
static ErrorStatus FaceOTA_SendUpgradePack(uint8_t *data, uint16_t len);

#endif /* __TEST_H__ */
